package com.vq.controller;

import com.vq.common.Code;
import com.vq.common.R;
import com.vq.common.UserLibrary;
import com.vq.entity.User;
import com.vq.entity.form.RegisterForm;
import com.vq.service.CaptchaService;
import com.vq.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.mail.MessagingException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@Slf4j
@Controller
@RequestMapping("/LogIn")
public class LogInController {
    @Autowired
    HttpSession session;
    @Autowired
    CaptchaService captchaService;
    @Autowired
    UserService userService;

    /**
     * 注册
     * @param registerForm 注册表
     * @return
     */
    @PostMapping
    @ResponseBody
    public R<User> register(@RequestBody RegisterForm registerForm) {
        R<User> r = new R<>(0);
        if(!captchaService.comparisonCaptcha("register", registerForm.getEmail(), registerForm.getCaptcha())) return r;
        //两次密码不相等
        if (!registerForm.getPassword1().equals(registerForm.getPassword2())) return r;
        //密码格式不符合格式（长度需要在6-20位之内，且须含有字母和数字）
        if(!registerForm.getPassword1().matches("^(?=.*[a-zA-Z])(?=.*\\d).{6,20}$")) return new R<>(Code.PASSWORD_FORMAT_NO);
        log.info("注册："+registerForm);
        User user = new User(registerForm.getEmail(), registerForm.getUsername(), registerForm.getPassword1());
        Integer bo = userService.insert(user);
        r = new R<>(bo, user);
        return r;
    }
    /**
     * 发送验证码
     * @param prefix
     * @param email
     * @return
     */
    @PostMapping("/{prefix},{email}")
    @ResponseBody
    public R sendCaptcha(@PathVariable String prefix, @PathVariable String email) throws MessagingException {
        String captcha = captchaService.sendCaptcha(prefix, email);
        log.info("发送验证码："+email);
        if (captcha==null) return new R(0);
        else return new R(1);
    }

    /**
     * 退出登录
     * @return
     */
    @DeleteMapping
    @ResponseBody
    public R<User> logOut(HttpServletResponse response) {
        User user = (User) session.getAttribute("myUser");
        if (user==null) return new R<>(0);
        //用户库中离线用户
        if(!UserLibrary.disUsers(user)) return new R<>(0);
        //清除全部数据
        session.invalidate();
        //创建Cookie对象
        Cookie c_account = new Cookie("account", "");
        Cookie c_password = new Cookie("password", "");
        //设置存活时间
        int time = 0;//24小时
        c_account.setMaxAge(time);
        c_password.setMaxAge(time);
        //发送cookie
        response.addCookie(c_account);
        response.addCookie(c_password);
        //记录日志
        log.info("退出登录："+user);
        return new R<>(1);
    }

    /**
     * 登录
     * @param response
     * @param accountOrEmail
     * @param password
     * @return
     * @throws IOException
     */
    @GetMapping
    @ResponseBody
    public R<User> logIn(HttpServletResponse response, @RequestParam("accountOrEmail") String accountOrEmail, @RequestParam("password") String password) throws IOException {
        R<User> r = new R<>(0);
        //1、判断是否已经登录
        User myUser = (User) session.getAttribute("myUser");//获取用户信息
        if (myUser!=null) return r;//已经登录
        //2、进行登录
        User user = userService.selectToAccPas(accountOrEmail, password);
        //该用户已经注册
        if (user != null) {
            int onlineNum = UserLibrary.newUsers(user);//向用户库存储用户信息，并且获取在线码
            user.setOnlineNum(onlineNum);//设置该用户在线码
            session.setAttribute("myUser", user);//向session域中存储用户信息
            //System.out.println(user+" "+user.getOnlineNum());
            //password = SecretKey.encipher(password);//加密
            //创建Cookie对象
            Cookie c_accountOrEmail = new Cookie("accountOrEmail", accountOrEmail);
            Cookie c_password = new Cookie("password", password);
            //设置存活时间
            int time = 60*60*24;//24小时
            c_accountOrEmail.setMaxAge(time);
            c_password.setMaxAge(time);
            //发送cookie
            response.addCookie(c_accountOrEmail);
            response.addCookie(c_password);
            //向响应消息中设置内容
            r.setCode(1);
            r.setData(user);
        } else {
//            password = SecretKey.decipher(password);//解密
//            user = userService.selectToAccPas(account, password);
//            if(user!=null) {
//                session.setAttribute("myUser", user);
//                result.setCode(1);
//                result.setData(user);
//            }
        }
        //记录日志
        log.info("登录："+user);
        return r;
    }
    /**
     * 查询自己用户信息
     * @return
     */
    @GetMapping("/selectMyUser")
    @ResponseBody
    public R<User> selectMyUser() {
        R<User> r = new R<>(0);
        User user = (User) session.getAttribute("myUser");
        if (user==null) {
            return r;
        }
        User u = new User(user.getId(), user.getEmail(), user.getUsername(), user.getAccount(), "");
        u.setFollowersNum(user.getFollowersNum());
        u.setFansNum(user.getFansNum());
        r.setCode(1);
        r.setData(u);
        //记录日志
        log.info("查询自己用户："+u);
        return r;
    }

    /**
     * 忘记密码
     * @param email
     * @param captcha
     * @param password
     * @return
     */
    @PutMapping
    @ResponseBody
    public R forgotPassword(@RequestParam("email") String  email, @RequestParam("captcha") String captcha, @RequestParam("password") String password) {
        //查看验证码是否正确
        boolean bo = captchaService.comparisonCaptcha("forgotPassword", email, captcha);
        if (!bo) return new R(0);
        //查看密码是否符合格式
        if(!password.matches("^(?=.*[a-zA-Z])(?=.*\\d).{6,20}$")) return new R<>(Code.PASSWORD_FORMAT_NO);
        //查看用户是否存在
        User user = userService.selectToEmail(email, true);
        if (user == null) return new R(0);
        //修改密码
        user.setPassword(password);
        return new R(userService.updateToPasswordById(user.getId(), null, password, true)?1:0);
    }
}
